#include "udp.h"

Udp::Udp(void)
{
	Open();
}
Udp::~Udp(void)
{
}
bool Udp::Open(void)
{
	if( -1 == m_fd )
	{
		m_fd = socket(AF_INET, SOCK_DGRAM, 0);
	}
	return (-1 != m_fd);
}
bool Udp::Bind(const string& ip, int port)
{
	struct sockaddr_in addr;

	if( -1 == m_fd || ip.empty() )
	{
		return true;
	}
	addr.sin_family = AF_INET;
	addr.sin_port = htons( port );
	addr.sin_addr.s_addr = htonl( inet_network(ip.data()) );

	int ret = bind(m_fd, (struct sockaddr*)&addr, (socklen_t)sizeof(addr));

	return (0 == ret);
}
bool Udp::Connect(const string& ip, int port)
{
	struct sockaddr_in addr;

	if( -1 == m_fd || ip.empty() )
	{
		return false;
	}
	addr.sin_family = AF_INET;
	addr.sin_port = htons( port );
	addr.sin_addr.s_addr = htonl( inet_network(ip.data()) );

	int ret = connect(m_fd, (struct sockaddr*)&addr, (socklen_t)sizeof(addr));

	return (0 == ret);
}
bool Udp::GetSocketName(string& ip, int& port)
{
	struct sockaddr_in addr;
	socklen_t slen = sizeof(addr);

	int ret = getsockname(m_fd, (struct sockaddr*)&addr, &slen);
	if( 0 == ret )
	{
		ip = inet_ntoa(addr.sin_addr);
		port = ntohs(addr.sin_port);
	}
	return (0 == ret);
}
int Udp::Send(const string& ip, int port, const void* data, int len)
{
	struct sockaddr_in addr;
	socklen_t slen = sizeof(addr);

	if( -1 == m_fd || ip.empty() || 0 == data || len < 1 )
	{
		return -1;
	}

	addr.sin_family = AF_INET;
	addr.sin_port = htons( port );
	addr.sin_addr.s_addr = htonl( inet_network(ip.data()) );

	return sendto(m_fd, data, len, 0, (struct sockaddr*)&addr, slen);
}
int Udp::Recv(string& ip, int& port, void* buf, int len)
{
	struct sockaddr_in addr;
	socklen_t slen = sizeof(addr);

	if( -1 == m_fd || 0 == buf || len < 1 )
	{
		return -1;
	}
	int ret = recvfrom(m_fd, buf, len, 0, (struct sockaddr*)&addr, &slen);
	if( ret > 0 )
	{
		port =  htons( addr.sin_port );
		ip = inet_ntoa( addr.sin_addr );
	}

	return ret;
}

